package com.caffeinatedbliss.nanowrimo.spike;

import com.caffeinatedbliss.nanowrimo.DynamicImageGenerator;
import com.caffeinatedbliss.nanowrimo.NanowrimoComputer;

import java.awt.*;
import java.awt.image.BufferedImage;

public class Graph_v1 implements DynamicImageGenerator {
  public static final Color LIGHTEST_GREY = new Color(0xee, 0xee, 0xee);
  public static final Color GREEN_INK = new Color(0x00, 0xcc, 0x00);
  public static final int WIDTH = 140;
  public static final int HEIGHT = 204;

  private BufferedImage graphImage;

  public Graph_v1(String history) {

    NanowrimoComputer computer = new NanowrimoComputer(history, 50000);
    int[] historyCounts = computer.getHistoryCounts();
    int current = computer.getCurrent();
    double percentComplete = computer.getPercentComplete();
    int daysLeftNaNoWriMo = computer.getDaysLeftNaNoWriMo();
    int[] expectedDayAmount = computer.getExpectedPerDayAmount();
    int maxAmount = computer.getMaxAmount();

    int green = (int) (2 + (WIDTH - 10) * percentComplete / 100.0);

    graphImage = new BufferedImage(WIDTH, HEIGHT, BufferedImage.TYPE_INT_RGB);
    Graphics g = graphImage.getGraphics();

    // Draw background
    g.setColor(LIGHTEST_GREY);
    g.fillRect(1, 1, WIDTH - 2, HEIGHT - 2);
    g.setColor(Color.black);
    g.drawRect(0, 0, WIDTH, HEIGHT);

    Font textFont = new Font("dialog", Font.BOLD, 11);
    String wordCount = current + " words";
    g.setFont(textFont);
    FontMetrics fm = g.getFontMetrics(textFont);
    int ascent = fm.getAscent();
    int descent = fm.getDescent();
    int totalLineHeght = ascent + descent;
    int wordCountWidth = fm.stringWidth(wordCount);
    int leftEdgeWordCount = (WIDTH - wordCountWidth) / 2;
    g.drawString(wordCount, leftEdgeWordCount, totalLineHeght);

    String dayCount = daysLeftNaNoWriMo + " Day" + ((daysLeftNaNoWriMo != 1) ? "s" : "") + " left";
    wordCountWidth = fm.stringWidth(dayCount);
    leftEdgeWordCount = 70 - wordCountWidth / 2;
    g.drawString(dayCount, leftEdgeWordCount, totalLineHeght * 2 + 15);

    // Draw graph boxes
    g.drawRect(3, totalLineHeght + 2, WIDTH - 8, 12);
    g.drawRect(3, totalLineHeght * 2 + 18, WIDTH - 8, HEIGHT - totalLineHeght * 2 - 23);
    g.setColor(Color.WHITE);
    g.fillRect(4, totalLineHeght * 2 + 19, WIDTH - 10, HEIGHT - totalLineHeght * 2 - 24);

    // Draw tasteful shadows and boundries
    g.setColor(Color.GRAY);
    g.drawLine(5, totalLineHeght + 15, WIDTH - 4, totalLineHeght + 15);
    g.drawLine(WIDTH - 4, totalLineHeght + 4, WIDTH - 4, totalLineHeght + 15);
    g.drawLine(5, HEIGHT - 4, WIDTH - 4, HEIGHT - 4);
    g.drawLine(WIDTH - 4, totalLineHeght * 2 + 20, WIDTH - 4, HEIGHT - 4);
    g.setColor(Color.LIGHT_GRAY);
    g.drawLine(7, totalLineHeght + 16, WIDTH - 3, totalLineHeght + 16);
    g.drawLine(137, totalLineHeght + 6, WIDTH - 3, totalLineHeght + 16);
    g.drawLine(7, HEIGHT - 3, WIDTH - 3, HEIGHT - 3);
    g.drawLine(137, HEIGHT - 3, WIDTH - 3, totalLineHeght * 2 + 22);

    // Draw overall % bar
    g.setColor(GREEN_INK);
    g.fillRect(4, totalLineHeght + 3, green, 11);
    g.setColor(Color.RED);
    g.fillRect(4 + green, totalLineHeght + 3, WIDTH - 9 - green, 11);
    g.setColor(Color.BLACK);
    g.drawLine(3 + green, totalLineHeght + 3, 3 + green, totalLineHeght + 13);

    for (int i = 0; i < expectedDayAmount.length; i++) {
      int written = 0;
      boolean useRed = false;
      if (i < historyCounts.length) {
        written = historyCounts[i];
        useRed = true;
      }

      int greenWidth = (int) ((WIDTH - 10.0) / (double) maxAmount * written);
      int greyWidth = (int) ((WIDTH - 10.0) / (double) maxAmount * expectedDayAmount[i]);

      if (greyWidth > greenWidth) {
        g.setColor((useRed) ? Color.RED : Color.GRAY);
        g.fillRect(4, totalLineHeght * 2 + 19 + (i * 5), greyWidth, 4);
        g.setColor(GREEN_INK);
        g.fillRect(4, totalLineHeght * 2 + 19 + (i * 5), greenWidth, 4);
      } else {
        g.setColor(GREEN_INK);
        g.fillRect(4, totalLineHeght * 2 + 19 + (i * 5), greenWidth, 4);
        g.setColor(Color.LIGHT_GRAY);
        g.fillRect(4, totalLineHeght * 2 + 19 + (i * 5), greyWidth, 4);
      }
    }

    // Cleanup and send to client
    g.dispose();
  }

  public BufferedImage getGraphImage() {
    return graphImage;
  }
}
